// TreeCountView.cpp : implementation file
//

#include "stdafx.h"
#include "finance.h"

#include "financedef.h"
#include "CDataFile.h"

#include "FinanceDoc.h"
#include "FinanceView.h"
#include "SearchView.h"
#include "TreeCountView.h"
#include "DlgSearch.h"
#include "DlgCountMonth.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



extern CFinanceApp theApp;       



/////////////////////////////////////////////////////////////////////////////
// CTreeCountView

IMPLEMENT_DYNCREATE(CTreeCountView, CColumnTreeView)

CTreeCountView::CTreeCountView()
{
	m_lYear = 0;
}

CTreeCountView::~CTreeCountView()
{
}


BEGIN_MESSAGE_MAP(CTreeCountView, CColumnTreeView)
	//{{AFX_MSG_MAP(CTreeCountView)
	ON_NOTIFY(NM_RCLICK, TreeID, OnRclickTreeCtrl)
	ON_COMMAND(ID_SEARCH, OnSearch)
	ON_COMMAND(ID_COUNT_YEAR, OnCountYear)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTreeCountView drawing

void CTreeCountView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CTreeCountView diagnostics

#ifdef _DEBUG
void CTreeCountView::AssertValid() const
{
	CView::AssertValid();
}

void CTreeCountView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTreeCountView message handlers

//
//------------------------------------------------------------
void CTreeCountView::OnInitialUpdate() 
{
	CColumnTreeView::OnInitialUpdate();
	

	// <> _CommandPtr init
	m_pCommand.CreateInstance(__uuidof(Command));
	m_pCommand->ActiveConnection = theApp.m_pConnection.GetInterfacePtr();
	
	// <> Init tree view
	CTreeCtrl& tree = GetTreeCtrl();
	CHeaderCtrl& header = GetHeaderCtrl();
	

	DWORD dwStyle = GetWindowLong(tree, GWL_STYLE);
	dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
	SetWindowLong(tree, GWL_STYLE, dwStyle);
	
	m_imagelist.Create(IDB_TREEIMG, 16, 1, RGB(255,0,255));
	tree.SetImageList(&m_imagelist, TVSIL_NORMAL);

	CFont			m_font;
	m_font.CreateFont(16, 0,0,0,FW_NORMAL, 0,0,0,
		DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
		DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
	tree.SetFont(&m_font);
	
	HDITEM hditem;
	hditem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
	hditem.fmt = HDF_CENTER | HDF_STRING;
	hditem.cxy = 160;
	hditem.pszText = "Year - Month";
	header.InsertItem(0, &hditem);
	hditem.cxy = 100;
	hditem.pszText = "Amount";
	header.InsertItem(1, &hditem);
	hditem.cxy = 100;
	hditem.pszText = "Comment";
	header.InsertItem(2, &hditem);
	UpdateColumns();

	// reset tree
	GetTreeCtrl().DeleteAllItems();	
	
	// <> Count by month and into Tree view
	CountbyMonth();

	// <>
	CountInvestTotal();

	// <> 
	CountBankTotal();
}

//
// count by month and into tree view
// the first month until now
//------------------------------------------------------------
void CTreeCountView::CountbyMonth()
{
	CTreeCtrl&		tree = GetTreeCtrl();
	_RecordsetPtr	pRecSet;
	_variant_t		var;
	LONG			lCount = 0;
	DOUBLE			dbSum = 0;
	CHAR			chSQL[INI_MAX_BUFLEN+100] = { 0 };
	CHAR			chDate[50] = { 0 };
	CHAR			chDateBeg[50] = { 0 };
	CHAR			chDateEnd[50] = { 0 };
	CHAR			chDateRange[100] = { 0 };
	CString			csTmp;
	CTime			ctFirst;
	CTime			ctCur = CTime::GetCurrentTime();
						//	Month : 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12
	INT				iMdays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	INT				i, j;
	

	
	// <> Find the first year/month in Account table
	strcpy( chSQL, "SELECT Date FROM Account ORDER BY Date ASC" );
	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );

		if( !pRecSet->adoEOF )
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			else
				csTmp.Empty();	
		}
		else
		{
			pRecSet->Close();
			return ;
		}

		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}

	// "2005/7/9" or "2005/12/31"
	ctFirst = DTString2CTime( csTmp ); 

	// <> Calculate by month 
	INT			iMonthBeg, iMonthEnd;
	HTREEITEM	hRoot, hSubRoot;

	for( i=ctFirst.GetYear(); i<=ctCur.GetYear(); i++ )	// every year
	{
		if( ctFirst.GetYear() == i ) 
			iMonthBeg = ctFirst.GetMonth();
		else
			iMonthBeg = 1;

		if( ctCur.GetYear() == i ) 
			iMonthEnd = ctCur.GetMonth();
		else
			iMonthEnd = 12;
		
		// Insert year as root in tree
		sprintf( chDate, "%d", i );
		hRoot = tree.InsertItem( chDate, 0, 5, TVI_ROOT );
		// <> flag for count
		tree.SetItemData( hRoot, i );

		strcpy( chDateBeg, chDate );
		strcpy( chDateEnd, chDate );
		// count by year
		if( wtkGetSysLanguage() == WTK_BIG5 ) 
		{
			strcat( chDateBeg, "/1/1" );
			strcat( chDateEnd, "/12/31" );
		}
		else
		{
			strcat( chDateBeg, "-01-01" );
			strcat( chDateEnd, "-12-31" );
		}
		sprintf( chDateRange, "WHERE Date >=#%s# AND Date <=#%s#", chDateBeg, chDateEnd ); 
		// <> Compose SQL 
		sprintf( chSQL, "SELECT FlowClass,SUM(Amount) FROM Account " );
		strcat( chSQL, chDateRange );
		strcat( chSQL, " GROUP BY FlowClass" );
		try
		{
			m_pCommand->CommandText = chSQL;
			pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
			
			while(!pRecSet->adoEOF)
			{
				var = pRecSet->GetCollect( (_variant_t)(long)0 );
				if(var.vt != VT_NULL)
					strcpy( chDateRange, (LPCSTR)_bstr_t(var) );
				else
					strcpy( chDateRange, "" );
				
				var = pRecSet->GetCollect( (_variant_t)(long)1 );
				switch( var.vt ) 
				{
				case VT_I4:	// long
					dbSum = var.lVal;
					break ;
					
				case VT_R4: // float
					dbSum = var.fltVal;
					break ;
					
				case VT_R8: // double
					dbSum = var.dblVal;
					break ;
					
				default :
					dbSum = 0;
					break ;
				}
				
				// Insert flowclass, sum(amount) as leaf in tree
				sprintf( chSQL, "%s\t%.2f\t", chDateRange, dbSum );
				tree.InsertItem( chSQL, 1, 1, hRoot );
				
				pRecSet->MoveNext();
			}
			
			pRecSet->Close();
		}
		catch(_com_error *e)
		{
			AfxMessageBox(e->ErrorMessage());
		}
		
		// <> Count by every month
		for( j=iMonthBeg; j<=iMonthEnd; j++ )	// every month
		{	// i is year, j is month
			if( wtkGetSysLanguage() == WTK_BIG5 ) 
				sprintf( chDate, "%d/%d", i, j );
			else
				sprintf( chDate, "%d-%d", i, j );

			strcpy( chDateBeg, chDate );
			strcat( chDateBeg, "/1" );
			sprintf( chDateEnd, "%s/%d", chDate, iMdays[j] );
			sprintf( chDateRange, "WHERE Date >=#%s# AND Date <=#%s#", chDateBeg, chDateEnd ); 

			// <> Compose SQL 
			sprintf( chSQL, "SELECT FlowClass,SUM(Amount) FROM Account " );
			strcat( chSQL, chDateRange );
			strcat( chSQL, " GROUP BY FlowClass" );
			try
			{
				m_pCommand->CommandText = chSQL;
				pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );

				// Insert month as sub-root in tree only When SUM(Amount) is not NULL
				if( !pRecSet->adoEOF )
					hSubRoot = tree.InsertItem( chDate, 2, 3, hRoot );
				
				while(!pRecSet->adoEOF)
				{
					var = pRecSet->GetCollect( (_variant_t)(long)0 );
					if(var.vt != VT_NULL)
						strcpy( chDateRange, (LPCSTR)_bstr_t(var) );
					else
						strcpy( chDateRange, "" );
					
					var = pRecSet->GetCollect( (_variant_t)(long)1 );
					switch( var.vt ) 
					{
					case VT_I4:	// long
						dbSum = var.lVal;
						break ;
						
					case VT_R4: // float
						dbSum = var.fltVal;
						break ;
						
					case VT_R8: // double
						dbSum = var.dblVal;
						break ;
						
					default :
						dbSum = 0;
						break ;
					}
					
					// Insert flowclass, sum(amount) as leaf in tree
					sprintf( chSQL, "%s\t%.2f\t", chDateRange, dbSum );
					tree.InsertItem( chSQL, 4, 4, hSubRoot );
					
					pRecSet->MoveNext();
				}
				
				pRecSet->Close();
			}
			catch(_com_error *e)
			{
				AfxMessageBox(e->ErrorMessage());
			}
		}	// month for{}
	} // year for{}

	tree.Expand( hSubRoot, TVE_EXPAND );
	tree.Expand( hRoot, TVE_EXPAND);
}

// 
// 
//--------------------------------------------------------------
void CTreeCountView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
/*
	if( bActivate ) 
	{
		// reset tree
		GetTreeCtrl().DeleteAllItems();	

		// <> Count by month and into Tree view
		CountbyMonth();

		CountBankTotal();
	}
*/

	CColumnTreeView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}

// 
// 
//--------------------------------------------------------------
void CTreeCountView::OnSearch() 
{
	CDlgSearch		dlg;
	
	
	if( dlg.DoModal() == IDOK ) 
	{
		CSearchView		*pView = NULL;
		CFinanceDoc		*pDoc=(CFinanceDoc*)GetDocument();
		
		if( pDoc )
			pView=(CSearchView*)pDoc->GetView(RUNTIME_CLASS(CSearchView));
		
		if( pView )
			pView->RefreshSearchView();
	}
}

//
// Count account Bank where Operation='Store'
//------------------------------------------------------------
void CTreeCountView::CountBankTotal()
{
	CTreeCtrl&		tree = GetTreeCtrl();
	_RecordsetPtr	pRecSet;
	_variant_t		var;
	CHAR			chSQL[INI_MAX_BUFLEN+100] = { 0 };
	CHAR			chName[100] = { 0 };
	LONG			lCount = 0;
	DOUBLE			dbSum = 0;
	HTREEITEM		hRoot;
	

	// <> Total account where Operation='Store'
	strcpy( chSQL, "SELECT SUM(Account) FROM Bankbook WHERE Operation='Store'" );
	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
		
		if( !pRecSet->adoEOF )
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			switch( var.vt ) 
			{
			case VT_I4:	// long
				dbSum = var.lVal;
				break ;
				
			case VT_R4: // float
				dbSum = var.fltVal;
				break ;
				
			case VT_R8: // double
				dbSum = var.dblVal;
				break ;
				
			default :
				dbSum = 0;
				break ;
			}
			
			strcpy( chName, "Bank stored" );
			// Insert Bankname, sum(Account) as leaf in tree
			sprintf( chSQL, "%s\t%.2f\t", chName, dbSum );
			hRoot = tree.InsertItem( chSQL, 0, 5, TVI_ROOT );
		}

		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	// <> Group by Bankname where Operation='Store'
	strcpy( chSQL, "SELECT Bankname,SUM(Account) FROM Bankbook WHERE Operation='Store' GROUP BY Bankname" );
	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
		
		while(!pRecSet->adoEOF)
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			if(var.vt != VT_NULL)
				strcpy( chName, (LPCSTR)_bstr_t(var) );
			else
				strcpy( chName, "" );
			
			var = pRecSet->GetCollect( (_variant_t)(long)1 );
			switch( var.vt ) 
			{
			case VT_I4:	// long
				dbSum = var.lVal;
				break ;
				
			case VT_R4: // float
				dbSum = var.fltVal;
				break ;
				
			case VT_R8: // double
				dbSum = var.dblVal;
				break ;
				
			default :
				dbSum = 0;
				break ;
			}
			
			// Insert Bankname, sum(Account) as leaf in tree
			sprintf( chSQL, "%s\t%.2f\t", chName, dbSum );
			tree.InsertItem( chSQL, 6, 6, hRoot );
			
			pRecSet->MoveNext();
		}
		
		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
}


// 
// 
//-------------------------------------------------------------------------------
void CTreeCountView::OnRclickTreeCtrl(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CColumnTreeCtrl&	tree = (CColumnTreeCtrl&)GetTreeCtrl();

	
	CPoint point;
	::GetCursorPos(&point);
	tree.ScreenToClient( &point );
		
	HTREEITEM hItem = tree.GetFirstColItem( point );
	if( hItem != NULL ) 
	{
		// Be set Itemdata in CTreeCountView::CountbyMonth()
		m_lYear = tree.GetItemData( hItem );
		if( m_lYear > 0 ) 
		{
			CMenu	menu;
			CPoint	pt;
			::GetCursorPos(&pt);
			
			menu.LoadMenu(IDR_RCK_TREECOUNT);
			CMenu* pMenu=menu.GetSubMenu(0);
			pMenu->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,this,NULL);
		}
	}

	*pResult = 0;
}

// 
//--------------------------------------------------------------
void CTreeCountView::OnCountYear() 
{
	CDlgCountMonth		dlg;
	
	CSearchView		*pView = NULL;
	CFinanceDoc		*pDoc=(CFinanceDoc*)GetDocument();
	
	if( pDoc )
		pView=(CSearchView*)pDoc->GetView(RUNTIME_CLASS(CSearchView));
	
	if( pView )
		dlg.SetViewPtr( pView );
	
	dlg.SetYear( m_lYear );
	
	dlg.DoModal();
}

//
// Count account 
//------------------------------------------------------------
void CTreeCountView::CountInvestTotal()
{
	CTreeCtrl&		tree = GetTreeCtrl();
	_RecordsetPtr	pRecSet;
	_variant_t		var;
	CHAR			chSQL[INI_MAX_BUFLEN+100] = { 0 };
	CHAR			chName[100] = { 0 };
	LONG			lCount = 0;
	DOUBLE			dbSum = 0;
	HTREEITEM		hRoot;
	

	// <> Total account 
	strcpy( chSQL, "SELECT SUM(Amount) FROM Account WHERE FlowClass='Invest'" );
	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
		
		if( !pRecSet->adoEOF )
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			switch( var.vt ) 
			{
			case VT_I4:	// long
				dbSum = var.lVal;
				break ;
				
			case VT_R4: // float
				dbSum = var.fltVal;
				break ;
				
			case VT_R8: // double
				dbSum = var.dblVal;
				break ;
				
			default :
				dbSum = 0;
				break ;
			}
			
			strcpy( chName, "Investment" );

			sprintf( chSQL, "%s\t%.2f\t", chName, dbSum );
			hRoot = tree.InsertItem( chSQL, 0, 5, TVI_ROOT );
		}

		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	// <> Group by Bankname where Operation='Store'
	strcpy( chSQL, "SELECT Purpose,SUM(Amount) FROM Account WHERE FlowClass='Invest' GROUP BY Purpose" );
	try
	{
		m_pCommand->CommandText = chSQL;
		pRecSet = m_pCommand->Execute( NULL, NULL, adCmdText );
		
		while(!pRecSet->adoEOF)
		{
			var = pRecSet->GetCollect( (_variant_t)(long)0 );
			if(var.vt != VT_NULL)
				strcpy( chName, (LPCSTR)_bstr_t(var) );
			else
				strcpy( chName, "" );
			
			var = pRecSet->GetCollect( (_variant_t)(long)1 );
			switch( var.vt ) 
			{
			case VT_I4:	// long
				dbSum = var.lVal;
				break ;
				
			case VT_R4: // float
				dbSum = var.fltVal;
				break ;
				
			case VT_R8: // double
				dbSum = var.dblVal;
				break ;
				
			default :
				dbSum = 0;
				break ;
			}
			
			sprintf( chSQL, "%s\t%.2f\t", chName, dbSum );
			tree.InsertItem( chSQL, 6, 6, hRoot );
			
			pRecSet->MoveNext();
		}
		
		pRecSet->Close();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
}
